<?php

/**
 * main actions.
 *
 * @package    liannot
 * @subpackage main
 * @author     Your name here
 * @version    SVN: $Id: actions.class.php 23810 2009-11-12 11:07:44Z Kris.Wallsmith $
 */
class mainActions extends sfActions
{
	/**
	 * Executes index action
	 *
	 * @param sfRequest $request A request object
	 */

	public function executeIndex(sfWebRequest $request)
	{
	}

	public function executeProjectList(sfWebRequest $request)
	{
		$this->project_list = Doctrine::getTable('Annoset')
		->createQuery('a')
		->where("a.user_name = ?",$this->getUser()->getUserName())
		->execute();
	}
	
	public function executeGetProjectListBis(sfWebRequest $request) {
		
		$annosetList = Doctrine::getTable('Annoset')
		->createQuery('a')
		->where("a.user_name = ?",$this->getUser()->getUserName())
		->execute();
		
		$annosets = array();
		
		foreach($annosetList as $annoset) {
			$annosets[$annoset->getId()]["name"] = $annoset->getName(); 
			$annosets[$annoset->getId()]["userName"] = $annoset->getUserName();
		}
		
		$json = json_encode($annosets,JSON_FORCE_OBJECT);
		echo $json;
		
		return sfView::NONE;
	}

	public function executeHideLayer(sfWebRequest $request)
	{
		$idAnnoset = $request->getParameter('annoset');
		$layer = $request->getParameter('layer');
		$table = $request->getParameter('table');
		$elements_to_hide = Doctrine::getTable($table)->createQuery('q')->select('q.att_id')
		->where('q.list_type = ?', $layer)->addWhere('q.id_annoset = ?', $idAnnoset)->execute();
		$this->ids_to_hide = array();
		foreach($elements_to_hide as $element){
			$this->ids_to_hide[] = $element->getAttId();
		}
		echo json_encode($this->ids_to_hide);
		return sfView::NONE;
	}
	
	public function executeDeleteProject(sfWebRequest $request) {
		$projectId = $request->getParameter("id");
		$this->deleted = false;
		if(!empty($projectId)) {
			$this->annoset = Doctrine::getTable('Annoset')->findOneById($projectId);
			if(!empty($this->annoset)) {
				if($this->annoset->getUserName() == $this->getUser()->getUserName()) {
					//	delete in the database
					$this->annoset->delete();
					
					$folder = sfConfig::get('sf_upload_dir')."/projects/".$this->annoset->getName()."/";
					//	delete projectFolder
					UseFulTools::deleteDirectory($folder);
					unlink(sfConfig::get('sf_upload_dir')."/initMediaFiles/".$this->annoset->getName().".xml");
					$this->deleted = true;
					$this->getUser()->setFlash('success',"Successful delete!");
				} else {
					$this->getUser()->setFlash('error',"You can't delete this project");
				}
					
			}
			
		} else {
			$this->getUser()->setFlash('error',"No Project Selected");
		}
		
		$this->redirect('main/projectList');
	}
	
	public function executeResetElementsPosition(sfWebRequest $request) {
		$annoset = Doctrine::getTable('Annoset')->find($request->getParameter('id'));
		if(empty($annoset))
			return sfView::NONE;
		Doctrine_Query::create()
		  ->update('Mark m')
		  ->set('m.x_position', '?', 'NULL')
		  ->where('m.id_annoset = ?', $annoset->getId())
		  ->execute();
		  
		Doctrine_Query::create()
		  ->update('Mark m')
		  ->set('m.y_position', '?', 'NULL')
		  ->where('m.id_annoset = ?', $annoset->getId())
		  ->execute();
		  
		Doctrine_Query::create()
		  ->update('Struct s')
		  ->set('s.x_position', '?', 'NULL')
		  ->where('s.id_annoset = ?', $annoset->getId())
		  ->execute();
		  
		Doctrine_Query::create()
		  ->update('Struct s')
		  ->set('s.y_position', '?', 'NULL')
		  ->where('s.id_annoset = ?', $annoset->getId())
		  ->execute();
		 
		 $this->redirect('main/openProject?id='.$annoset->getId());
	}

	public function executeOpenProject(sfWebRequest $request)
	{
		$this->annoset = Doctrine::getTable('Annoset')->find($request->getParameter('id'));
		
		if(!empty($this->annoset) && $this->annoset->getUserName() == $this->getUser()->getUserName()) {
			
				$this->uri = $request->getUri();
				$this->listTypes = $this->annoset->getListTypes();
				$id = $this->annoset->getId();
				$this->delimitersList = MarkTable::queryWithDistinctListType($id)->execute()->toArray();
		
				if($request->getParameter('delimiter'))
				$this->delimiter = $request->getParameter("delimiter");
				else
				$this->delimiter = "#";
				/*******************************test layers to hide************************************/
				$markLayers = Doctrine::getTable('Mark')->createQuery('m')->select('m.list_type')
				->where('m.id_annoset = ?', $id)->groupBy('m.list_type')
				->execute()->toArray();
				$this->layers = array();
				$this->layers['Mark'] = array();
				foreach($markLayers as $layer){
					$this->layers['Mark'][] = $layer;
				}
				$stuctLayers = Doctrine::getTable('Struct')->createQuery('s')->select('s.list_type')
				->where('s.id_annoset = ?', $id)->groupBy('s.list_type')->having('s.list_type != ?', 'annoSet')
				->execute()->toArray();
				$this->layers['Struct'] = array();
				foreach($stuctLayers as $layer){
					$this->layers['Struct'][] = $layer;
				}
				/****************************************/
				$this->delimitersIds = array();
				$this->delimiters = MarkTable::queryWithDelimiter($this->annoset->getId(), $this->delimiter)->execute();
				$this->index = 1;
				$this->action = '';
				if($request->getParameter('index'))
				$this->index = $request->getParameter('index');
				if($request->getParameter('action'))
				$this->action = $request->getParameter('action');
				$this->total = ($this->delimiters->count() != 0)? $this->delimiters->count() : 1;
				$this->tokens_by_dlmt = array();
				foreach($this->delimiters as $dlmt)
				{
					$this->delimitersIds[] = $dlmt->getAttId();
					if($this->delimiter != 'tok'){
						$href = Paula::XlinkToArray($dlmt->getHref());
						$this->tokens_by_dlmt[] = $href;
					}
					else
					$this->tokens_by_dlmt[] = $dlmt->getAttId();
				}
				if($this->delimiter != "#"){
					$this->tokens = Doctrine::getTable('Mark')->createQuery('m')
					->whereIn('m.att_id', $this->tokens_by_dlmt[$this->index - 1])->addWhere('m.list_type = ?', 'tok')
					->addWhere('m.id_annoset = ?', $id)->execute();
				}
				else{
					$this->tokens = Doctrine::getTable('Mark')->createQuery('m')
					->where('m.list_type = ?', 'tok')
					->addWhere('m.id_annoset = ?', $id)->execute();
					$this->delimitersIds[0] = ""; //to hack offset pb
				}
		
				$this->att_ids_list = array();
				foreach($this->tokens as $token){
					array_push($this->att_ids_list, $token->getAttId());
				}
				/***********************************************************************************************************/
		
				$this->marks = MarkTable::queryWithOutDelimiter($this->annoset->getId(), $this->delimiter)->execute();
				$this->structs = StructTable::queryWithRelsByIdAnnoset($this->annoset->getId())->execute();
				$this->feats_list = $this->annoset->getFeatsListTest();
				$rels = array();
				$entities = array();
				foreach($this->delimiters as $delimiter){
					$entity = array('table' => 'Mark', 'element' => $delimiter);
					$entities[$delimiter->getAttId()] = $entity;
				}
		
				foreach($this->marks as $mark){
					$entity = array('table' => 'Mark', 'element' => $mark);
					$entities[$mark->getAttId()] = $entity;
				}
		
				foreach($this->structs as $struct){
					$entity = array('table' => 'Struct', 'element' => $struct);
					$entities[$struct->getAttId()] = $entity;
					$struct_rels = $struct->getRels();
					if(!$struct_rels)
					$struct_rels = null;
					$rels[$struct->getAttId()] = $struct_rels;
				}
		
		
				$this->all_marks_level = array();
				$this->all_structs_level = array();
				$this->marks_level = array();
				$this->structs_level = array();
				$this->max_level = 0;
		
				foreach($this->marks as $mark):
				$element = Paula::getLevelTest($mark, $entities, $rels);
				$level = $element['level'];
				if($level > $this->max_level)
				$this->max_level = $level;
				$this->all_marks_level[$level][] = $element;
				endforeach;
		
				ksort($this->all_marks_level);
		
		
				foreach($this->structs as $struct):
				if($struct->getListType() != 'annoSet'):
				$element = Paula::getLevelTest($struct, $entities, $rels);
				$level = $element['level'];
				if($level > $this->max_level)
				$this->max_level = $level;
				$this->all_structs_level[$level][] = $element;
				endif;
				endforeach;
		
			 ksort($this->all_structs_level); //*/
		
		
			 foreach($this->all_marks_level as $level=>$entities){
			 	if($level == 0){
			 		foreach($entities as $entity){
			 			if(in_array($entity['element']->getAttId(), $this->att_ids_list))
			 			$this->marks_level[$level][] = $entity;
			 		}
			 	}
			 	else{
			 		foreach($entities as $entity){
			 			foreach($entity['sons'] as $son){
			 				if(in_array($son['son']->getAttId(), $this->att_ids_list)){
		
			 					array_push($this->att_ids_list, $entity['element']->getAttId());
			 					$this->marks_level[$level][] = $entity;
			 					break;
							 }
			 			}
			 		}
			 	}
			 }
		
			 foreach($this->all_structs_level as $level=>$entities){
			 	if($level == 0){
			 		$this->structs_level[$level] = $entities;
			 	}
			 	else{
			 		foreach($entities as $entity){
			 			foreach($entity['sons'] as $son){
			 				if(in_array($son['son']->getAttId(), $this->att_ids_list)||
			 				$son['son']->getAttId() == $this->delimitersIds[$this->index -1]){
			 					array_push($this->att_ids_list, $entity['element']->getAttId());
			 					$this->structs_level[$level][] = $entity;
			 					break;
							 }
			 			}
			 		}
			 	}
			 }
		
			 ksort($this->marks_level);
			 ksort($this->structs_level);
		} else {
					$this->getUser()->setFlash('error',"You can't open this project");
					$this->redirect("/frontend_dev.php/main/projectList");
		}
	}

	/*
	 * function ok, but not optimized
	 */
	public function executeDeleteElement(sfWebRequest $request){
		$idAnnoset = $request->getParameter('annoset');
		$annoset = Doctrine::getTable('annoset')->find($idAnnoset);
		$annosetName = $annoset->getName();
		$att_id = $request->getParameter('att_id');
		$list_type = $request->getParameter('list_type');
		$paula_id = $request->getParameter('paula_id');
		$file = Doctrine::getTable('File')->createQuery('f')->select('f.name, f.type')
		->where('f.id_annoset = ?', $idAnnoset)
		->addWhere('f.paula_id = ?', $paula_id)->execute();
		$tableOfElement = $file[0]->getType();
		$element_to_delete = Doctrine::getTable($tableOfElement)
		->findOneByAttIdAndIdAnnoset($att_id, $idAnnoset);
		$pattern = '%'.$att_id.'%';
		$structs =StructTable::queryWithRelsByIdAnnoset($idAnnoset)
		->addWhere('r.href LIKE ?', $pattern)->execute();
		/**************Structs******************/
		foreach($structs as $struct){
			$rels = $struct->getRels();
			$structFile = $struct->getFile();
			foreach($rels as $rel){
				/*TODO
				 * check href :
				 * if att_id is the only one linked, delete rel : first in files then in bdd (1)
				 * else update rel first in files then in bdd (2)
				 */
				//need function for checking href with att_id... a Paula one? -> currently a private method
				/********TEST*************/
				$href = $rel->getHref();
				if($this->checkHrefWithId($href, $att_id) == true){ // (1)
					$structFileName = $structFile->getName();
					$relId = $rel->getAttId();
					/*
					 * (a) delete in files...
					 * (b) find feats related to this rel then delete them (file + bdd)
					 * (c) delete in bdd...
					 */

					/*********(b)*********/
					$relPattern = '%'.$relId.'%';
					$feats = Doctrine::getTable('Feat')->createQuery('f')->select('f.*')
					->where('f.id_annoset = ?', $idAnnoset)->addWhere('f.href LIKE ?', $relPattern)
					->execute();
					foreach($feats as $feat){
						$featFile = Doctrine::getTable('File')->findOneByIdAnnosetAndPaulaId($idAnnoset, $feat->getPaulaId());
						$featFileName = $featFile->getName();
						$featHref = $feat->getHref();
						$this->deleteInFileByHref($featFileName, $featHref, $annosetName);
						$feat->delete();
					}
					/********end (b)*****/
					 	
					/********(a)***********/
					$this->deleteInFile($structFileName, $relId, 'rel', $annosetName);
					/********end (a)*******/
					 	
					/*********(c)**********/
					$rel->delete();
					/********end (c)*******/
				}
				else // (2)
				/*have to create a new href*/
				/*
				 * (a) update in files
				 * (b) update in bdd
				 */
				echo 'todo!\n';

				/********end TEST********/
			}
		}
		/*************end Structs********************/

		/*TODO
		 * check feats like structs
		 */
		/****************Feats*******************/

		$feats = Doctrine::getTable('Feat')->createQuery('f')->select('f.*')
		->where('f.id_annoset = ?', $idAnnoset)->addWhere('f.href LIKE ?', $pattern)->execute();
		foreach($feats as $feat){
			/*TODO
			 * check href:
			 * if att_id is the only one linked, delete feat : first in files, then in bdd
			 * else update feat first in files, then in bdd
			 */
			//need function for checking href with att_id... a Paula one?
			if($this->checkHrefWithId($feat->getHref(), $att_id) == true){
				$featFile = Doctrine::getTable('File')->findOneByIdAnnosetAndPaulaId($idAnnoset, $feat->getPaulaId());
				$featFileName = $featFile->getName();
				$featHref = $feat->getHref();
				$this->deleteInFileByHref($featFileName, $featHref, $annosetName);
				$feat->delete();
			}
		}

		/*****************endFeats***************/

		/*TODO
		 * delete element_to_delete first in files, then in bdd
		 * !!! Don't forget feats for links!!!! (if element is of type struct...)
		 */
		/*********element_to_delete************/
		/*first check type of element*/
		if($tableOfElement == 'Struct'){
			// if struct, delete feats for rels
			$rels = $element_to_delete->getRels();
			foreach($rels as $rel){
				$href = $rel->getHref();
				$relId = $rel->getAttId();
				$relPattern = '%'.$relId.'%';
				$feats = Doctrine::getTable('Feat')->createQuery('f')->select('f.*')
				->where('f.id_annoset = ?', $idAnnoset)->addWhere('f.href LIKE ?', $relPattern)
				->execute();
				foreach($feats as $feat){
					$featFile = Doctrine::getTable('File')->findOneByIdAnnosetAndPaulaId($idAnnoset, $feat->getPaulaId());
					$featFileName = $featFile->getName();
					$featHref = $feat->getHref();
					$this->deleteInFileByHref($featFileName, $featHref, $annosetName);
					$feat->delete();
				}
			}
		}

		/*then delete element in file*/
		$this->deleteInFile($file[0]->getName(), $att_id, strtolower($tableOfElement), $annosetName);
		/*finaly, delete element in bdd*/
		$element_to_delete->delete();
		/*********end_element_to_delete********/
		echo json_encode('success');
		return sfView::NONE;
	}

	public function executeDeleteStructLink(sfWebRequest $request){
		$idAnnoset = $request->getParameter('annoset');
		$annoset = Doctrine::getTable('annoset')->find($idAnnoset);
		$annosetName = $annoset->getName();
		$idRel = $request->getParameter('idRel');
		$rel_to_delete = Doctrine::getTable('Rel')->find($idRel);
		$struct = $rel_to_delete->getStruct();
		$file = $struct->getFile();
		$file_name = $file->getName();
		$pattern = '%'.$rel_to_delete->getAttId().'%';
		$feats = Doctrine::getTable('Feat')->createQuery('f')->select('f.*')
		->where('f.id_annoset = ?', $idAnnoset)
		->addWhere('f.href LIKE ?', $pattern)->execute();
		foreach($feats as $feat){
			$featFile = Doctrine::getTable('File')->findOneByIdAnnosetAndPaulaId($idAnnoset, $feat->getPaulaId());
			$featFileName = $featFile->getName();
			$featHref = $feat->getHref();
			$this->deleteInFileByHref($featFileName, $featHref, $annosetName);
			$feat->delete();
		}
		$this->deleteElementById($file_name, $rel_to_delete->getAttId(), $annosetName);
		$rel_to_delete->delete();
		echo json_encode("success");
		return sfView::NONE;
	}

	public function executeDeleteMarkLink(sfWebRequest $request){
		$idMark = $request->getParameter('elementId');
		$attIdDest = $request->getParameter('attIdDest');
		$mark = Doctrine::getTable('Mark')->find($idMark);
		$annosetName = $mark->getAnnoset()->getName();
		$file = $mark->getFile();
		$href = $mark->getHref();
		$tab = Paula::XlinkToArray($href);
		array_splice($tab, array_search($attIdDest, $tab), 1);
		$newHref = Paula::arrayToXlink($tab);
		//update in files
		$this->updateHrefInFile($file->getName(), 'mark', $href, $newHref, $annosetName);
		//update in db
		$mark->setHref($newHref);
		$mark->save();
		echo json_encode("success");
		return sfView::NONE;
	}

	public function executeSetFeats(sfWebRequest $request){
		$id_annoset = $request->getParameter('annoset');
		$annoset = Doctrine::getTable('Annoset')->find($id_annoset);
		$elementId = $request->getParameter('elementId');
		$json = $request->getParameter('json');
		$newFeats = json_decode($json, true);
		$paula_id = $request->getParameter('paula_id');
		$elementFile = Doctrine::getTable('File')->findOneByIdAnnosetAndPaulaId($id_annoset,
		$paula_id);
		$elementFileName = $elementFile->getName();
		$projectName = $annoset->getName();
		foreach($newFeats as $name=>$feat){
			if(!$feat['paula_id'])
			echo 'paula_id : NULL<br/>';
			/*
			 * TODO create new file?
			 */
			else{
				$featFile = Doctrine::getTable('File')->findOneByIdAnnosetAndPaulaId($id_annoset,
				$feat['paula_id']);
				$this->addFeat($projectName, $featFile->getName(),
				$name, $feat['value'], $elementId, $elementFileName, $id_annoset);
			}
		}
		return sfView::NONE;
	}
	
	public function executeGetFeatsListByLayers(sfWebRequest $request){
		$id = $request->getParameter("annoset");
		$annoset = Doctrine::getTable("annoset")->find($id);
		$marks = $annoset->getMarks();
		$featsLists = array();
		$this->feedListByElementType($featsLists, $marks, $id, 'Mark');
		$structs = $annoset->getStructs();
		$this->feedListByElementType($featsLists, $structs, $id, 'Struct');
		
		$tmpFeatLists = array();
		//	verification s'il n'y pas de tok dans la liste
		foreach($featsLists as $type=>$featsList){
			if($type != "tok" && $type != "turn") {
				$tmpFeatLists[$type] = $featsList;
			}
		}
		$featsLists = $tmpFeatLists;
		ksort($featsLists);
		
		foreach($featsLists as $type=>$featsList){
			ksort($featsLists[$type]['list']);
			foreach($featsList['list'] as $name=>$feats){
				asort($featsLists[$type]['list'][$name]['values']);
			}
		}
		$json = json_encode($featsLists);
		$this->getResponse()->setHttpHeader('Content-type', 'application/json');
		//$this->getResponse()->setContent(json_encode($featsLists));
		return $this->renderText($json);
		//return sfView::NONE;
	}
	
	public function executeGetElementFeatByHref(sfWebRequest $request) {
		$id_annoset = $request->getParameter("annoset");
		$href = "#".$request->getParameter("href");
		
		if(!empty($id_annoset) && !empty($href)) {
			$featList = Doctrine::getTable('Feat')
			->CreateQuery('f')->select()->where('f.id_annoset=?',$id_annoset)
			->addWhere('f.href = ?',$href)
			->execute();
			
			$feats = array();
			//frame_13_2_f00
			foreach($featList as $feat) {
				$feats[$feat->getName()] = $feat->getValue();
			}
			$json = json_encode($feats,JSON_FORCE_OBJECT);
			echo $json;
		}
		return sfView::NONE;
	}
	public function executeGetElementLinkByHrefAndId(sfWebRequest $request) {
		
		$id_annoset = $request->getParameter("annoset");
		$href = "#".$request->getParameter("href");
		$id = $request->getParameter("id");
		$paula_type = $request->getParameter("paula_type");
		if(!empty($id_annoset) && !empty($href) && !empty($id) && !empty($paula_type)) {
			
			$links = array();
			
			if($paula_type == "frame") {
				
				$struct =  Doctrine::getTable('struct')
				->findOneById($id);
				$relList = Doctrine::getTable('Rel')
				->CreateQuery('r')->select()->where('r.id_struct=?',$id)
				->execute();
				
				foreach($relList as $rel) {
					$link_id = $rel->getId();
					$source_id = $struct->getAttId();
					$dest_id = explode("#",$rel->getHref());
					$dest_id = $dest_id[1];
					
					$attId = $rel->getAttId();
					
					$featList = Doctrine::getTable('Feat')
						->CreateQuery('f')->select()->where('f.id_annoset=?',$id_annoset)
						->addWhere('f.href = ?',"#".$rel->getAttId())
						->execute();
					
					$text="";
					foreach($featList as $feat) {
						$text = $feat->getValue();
					}
					
					$linkElement = array();
					$linkElement["source"] = $source_id;
					$linkElement["dest"] = $dest_id;
					$linkElement["text"] = $text;
					$linkElement["attId"] = $attId;
					
					$links[$link_id] = $linkElement;
				}
				
			}
			
			//	Pour les element de type frame ou pas frame
			$relList = Doctrine::getTable('Rel')
				->CreateQuery('r')->select()->where('r.href  LIKE ?',"%$href")
				->execute();
				
				foreach($relList as $rel) {
					$link_id = $rel->getId();
					$struct =  Doctrine::getTable('struct')
						->findOneById($rel->getIdStruct());
					$source_id = $struct->getAttId();
					$dest_id = explode("#",$rel->getHref());
					$dest_id = $dest_id[1];
					
					$attId = $rel->getAttId();
					
					$featList = Doctrine::getTable('Feat')
						->CreateQuery('f')->select()->where('f.id_annoset=?',$id_annoset)
						->addWhere('f.href = ?',"#".$rel->getAttId())
						->execute();
					
					$text="";
					foreach($featList as $feat) {
						$text = $feat->getValue();
					}
					
					$linkElement = array();
					$linkElement["source"] = $source_id;
					$linkElement["dest"] = $dest_id;
					$linkElement["text"] = $text;
					$linkElement["attId"] = $attId;
					
					$links[$link_id] = $linkElement;
				}
				
			$json = json_encode($links,JSON_FORCE_OBJECT);
			echo $json;
			
		}
		
		return sfView::NONE;
	}
	
	
	public function executeGetFrameLinkFeats(sfWebRequest $request) {
		$id_annoset = $request->getParameter("annoset");
		$featList = Doctrine::getTable('Feat')
			->CreateQuery('f')->select()->where('f.id_annoset=?',$id_annoset)
			->addWhere('f.list_type = ?',"frame_links_feats")
			->execute();
		
		$featValues = array();
		
		foreach($featList as $feat) {
			array_push($featValues,$feat->getValue());
		}
		
		$json = json_encode(array_unique($featValues),JSON_FORCE_OBJECT);
		
		echo $json;
			
		return sfView::NONE;
	}
	
	public function executeGetFrameFeatsName(sfWebRequest $request) {
		$id_annoset = $request->getParameter("annoset");
		$featList = Doctrine::getTable('Feat')
			->CreateQuery('f')->select()->where('f.id_annoset=?',$id_annoset)
			->addWhere('f.list_type = ?',"frame_feats")
			->execute();
		
		$featValues = array();
		
		foreach($featList as $feat) {
			array_push($featValues,$feat->getName());
		}
		
		$json = json_encode(array_unique($featValues),JSON_FORCE_OBJECT);
		
		echo $json;
			
		return sfView::NONE;
	}
	
	public function executeGetAttFeatsName(sfWebRequest $request) {
		$id_annoset = $request->getParameter("annoset");
		$featList = Doctrine::getTable('Feat')
			->CreateQuery('f')->select()->where('f.id_annoset=?',$id_annoset)
			->addWhere('f.list_type = ?',"att_feats")
			->execute();
		
		$featValues = array();
		
		foreach($featList as $feat) {
			array_push($featValues,$feat->getName());
		}
		
		$json = json_encode(array_unique($featValues),JSON_FORCE_OBJECT);
		
		echo $json;
			
		return sfView::NONE;
	}
	
public function executeGetFrameFeatsValue(sfWebRequest $request) {
		$id_annoset = $request->getParameter("annoset");
		$featList = Doctrine::getTable('Feat')
			->CreateQuery('f')->select()->where('f.id_annoset=?',$id_annoset)
			->addWhere('f.list_type = ?',"frame_feats")
			->execute();
		
		$featValues = array();
		
		foreach($featList as $feat) {
			array_push($featValues,$feat->getValue());
		}
		
		$json = json_encode(array_unique($featValues),JSON_FORCE_OBJECT);
		
		echo $json;
			
		return sfView::NONE;
	}
	
	public function executeGetAttFeatsValue(sfWebRequest $request) {
		$id_annoset = $request->getParameter("annoset");
		$featList = Doctrine::getTable('Feat')
			->CreateQuery('f')->select()->where('f.id_annoset=?',$id_annoset)
			->addWhere('f.list_type = ?',"att_feats")
			->execute();
		
		$featValues = array();
		
		foreach($featList as $feat) {
			array_push($featValues,$feat->getValue());
		}
		
		$featValues = array_unique($featValues);
		
		$json = json_encode($featValues,JSON_FORCE_OBJECT);
		
		echo $json;
			
		return sfView::NONE;
	}
	
	public function executeGetFrameFeatsValueByName(sfWebRequest $request) {
		$id_annoset = $request->getParameter("annoset");
		$name = $request->getParameter("name");
		$featList = Doctrine::getTable('Feat')
			->CreateQuery('f')->select()->where('f.id_annoset=?',$id_annoset)
			->addWhere('f.list_type = ?',"frame_feats")
			->addWhere('f.name = ?',$name)
			->execute();
		
		$featValues = array();
		
		foreach($featList as $feat) {
			array_push($featValues,$feat->getValue());
		}
		
		$json = json_encode(array_unique($featValues),JSON_FORCE_OBJECT);
		
		echo $json;
			
		return sfView::NONE;
	}
	
	public function executeGetAttFeatsValueByName(sfWebRequest $request) {
		$id_annoset = $request->getParameter("annoset");
		$featList = Doctrine::getTable('Feat')
			->CreateQuery('f')->select()->where('f.id_annoset=?',$id_annoset)
			->addWhere('f.list_type = ?',"att_feats")
			->addWhere('f.name = ?',$name)
			->execute();
		
		$featValues = array();
		
		foreach($featList as $feat) {
			array_push($featValues,$feat->getValue());
		}
		
		$featValues = array_unique($featValues);
		
		$json = json_encode($featValues,JSON_FORCE_OBJECT);
		
		echo $json;
			
		return sfView::NONE;
	}
	
	public function executeGetProjectList(sfWebRequest $request) {
		$project_list = Doctrine::getTable('Annoset')
		->createQuery('a')
		->where("a.user_name = ?",$this->getUser()->getUserName())
		->execute();
		
		$annosetNameList = array();
		foreach($project_list as $tmp) {
			array_push($annosetNameList,$tmp->getName());
		}
		ksort($annosetNameList);
		$json = json_encode($annosetNameList);
		echo ($json);
		//$this->getResponse()->setHttpHeader('Content-type', 'application/json');
		return sfView::NONE;
	}
	
	/**
	 * Check if the rel passed by get method is alterable or not (rel is alterable id one of node is a frame)
	 * @param sfWebRequest $request
	 */
	public function executeCheckAlterableRel(sfWebRequest $request) {
		$idRel = $request->getParameter("idRel");
		if(!empty($idRel)){
			$rel = Doctrine::getTable('rel')
			->findOneById($idRel);
			if(!empty($rel)) {
				echo json_encode(array('alterable'=>true ));
			}else {
				echo json_encode(array('alterable'=>false));
			}
			
		}else {
			echo json_encode(array('alterable'=>false));
		}
		return sfView::NONE;
	}
	
	/**
	 * Chanle a link text. Rel id and New text is provided by GET method
	 * @param $request
	 */
	public function executeChangeLinkText(sfWebRequest $request) {
		$idRel = $request->getParameter("idRel");
		$text = $request->getParameter("text");
		if(!empty($idRel)){
			$rel = Doctrine::getTable('rel')
			->findOneById($idRel);
			if(!empty($rel)) {
				$struct = Doctrine::getTable('struct')
				->findOneById($rel->getIdStruct());
				
				if(!empty($struct)) {
					$annoset= Doctrine::getTable('annoset')
					->findOneById($struct->getIdAnnoset());
					
					//	verification si l'enregistrement existe deja (Modification ou bien suppression)
					$exists = Doctrine::getTable('Feat')
					->CreateQuery('f')->select()->where('f.id_annoset=?',$annoset->getId())
					->addWhere(' f.href=?' , "#".$rel->getAttId())
					->execute();
					//	existe deja
					if(count($exists) > 0) {
						if(empty($text)) {
							//	text est vide cela veux dire qu'on peut l'effacer
							foreach($exists as $actualFeat) {
								$actualFeat->delete();
							}
						} else {
							//	 ici on doit modifier le text
							
							foreach($exists as $actualFeat);
							Doctrine_Query::create()
								->update('Feat f')
								->set('f.value','?',$text)
								->where('f.id = ?',$actualFeat->getId())
								->execute();
							
						}
					} else {
						// n'existe pas encore
						
						if(!empty($text)) {
							// on rajoute si ce n'est pas vide	
							$Feat = new Feat();
							$Feat->setIdAnnoset($annoset->getId());
							$Feat->setPaulaId($annoset->getName().".frame_links_feats");
							$Feat->setBase($annoset->getName().".frame.xml");
							$Feat->setListType("frame_links_feats");
							$Feat->setHref("#".$rel->getAttId());
							$Feat->setValue($text);
							$Feat->save();
						}
					}
				}
				echo json_encode(array('changed'=>true));
			} else {
				echo json_encode(array('changed'=>false));
			}
			
		}else {
			echo json_encode(array('changed'=>false));
		}
		return sfView::NONE;
	}
	
	/**
	 * Check if this is a features or not by id_annoset,href,name,value
	 * @param sfWebRequest $request
	 */
	public function executeIsFeatures(sfWebRequest $request) {
		$idAnnoset = $request->getParameter("idAnnoset");
		$href = $request->getParameter("href");
		$name = $request->getParameter("name");
		
		if(!empty($idAnnoset) && !empty($href) && !empty($name)) {
			$feat_list = Doctrine::getTable("Feat")
				->CreateQuery('f')
				->select()
				->where('f.id_annoset=?',$idAnnoset)
				->addWhere("f.href=?",$href)
				->addWhere("f.name=?",$name)
				->execute();
			if(count($feat_list) > 0){
				echo json_encode(array('isFeat'=>true));
			} else {
				echo json_encode(array('isFeat'=>false));
			}
		}else {
			echo json_encode(array('isFeat'=>false));
		}
		return sfView::NONE;
	}
	
	/**
	 * Update features 
	 * @param sfWebRequest $request
	 */
	public function executeUpdateFeatures(sfWebRequest $request) {
		$idAnnoset = $request->getParameter("idAnnoset");
		$href = $request->getParameter("href");
		$name = $request->getParameter("name");
		$value = $request->getParameter("value");
		
		if(!empty($idAnnoset) && !empty($href) && !empty($name) && isset($value)) {
			Doctrine_Query::create()
				->update('Feat f')
				->set('f.value','?',$value)
				->where('f.id_annoset=?',$idAnnoset)
				->addWhere("f.href=?",$href)
				->addWhere("f.name=?",$name)
				->execute();
			echo json_encode(array('succed'=>true));
		}else {
			echo json_encode(array('succed'=>false));
		}
		return sfView::NONE;
	}
	
	public function executeAddFeature(sfWebRequest $request) {
		$idAnnoset = $request->getParameter("idAnnoset");
		$href = $request->getParameter("href");
		$name = $request->getParameter("name");
		$value = $request->getParameter("value");
		$annoset= Doctrine::getTable('annoset')
			->findOneById($idAnnoset);
		
		
		if(!empty($idAnnoset) && !empty($href) && !empty($name) && isset($value)) {
			
			$elementType = explode("_",$href);
			$elementType = explode("#",$elementType[0]);
			$elementType = $elementType[1];
			
			
			$Feat = new Feat();
			$Feat->setIdAnnoset($idAnnoset);
			$Feat->setPaulaId($annoset->getName().".".$elementType."_feats");
			$Feat->setBase($annoset->getName().".$elementType.xml");
			$Feat->setListType($elementType."_feats");
			$Feat->setHref($href);
			$Feat->setName($name);
			$Feat->setValue($value);
			$Feat->save();
			echo json_encode(array('succed'=>true));
		}else {
			echo json_encode(array('succed'=>false));
		}
		
		return sfView::NONE;
	}
	
	public function executeDeleteFeature(sfWebRequest $request) {
		$idAnnoset = $request->getParameter("idAnnoset");
		$href = $request->getParameter("href");
		$name = $request->getParameter("name");
		if(!empty($idAnnoset) && !empty($href) && !empty($name)) {
			$feats = Doctrine::getTable('Feat')
				->createQuery('f')
				->where('f.id_annoset = ?', $idAnnoset)
				->addWhere('f.href = ?', $href)
				->addWhere('f.name = ?',$name)
				->execute();
			
			foreach($feats as $feat) {
				$feat->delete();
			}
		echo json_encode(array('succed'=>true));
		}else {
			echo json_encode(array('succed'=>false));
		}
		return sfView::NONE;
	}
	
	public function executeCreateElement(sfWebRequest $request){
		$id_annoset = $request->getParameter("annoset");
		$annoset = Doctrine::getTable("annoset")->find($id_annoset);
		$projectName = $annoset->getName();
		$table = $request->getParameter('table');
		$type = $request->getParameter('type');
		$test = Doctrine::getTable($table)
		->findOneByIdAnnosetAndListType($id_annoset, $type);
		
		$paula_id = $test->getPaulaId();
		
		
		
		$base = $test->getBase();
		$fileName = $test->getFile()->getName();
		if($table == 'Mark'){
			$element = new Mark();
			$element->setHref("");
		}
		elseif($table == 'Struct')
		$element = new Struct();
		$element->setIdAnnoset($id_annoset);
		$element->setPaulaId($paula_id);
		$element->setListType($type);
		if($base !== null)
		$element->setBase($base);
		$element->save();
		$id = $element->getId();
		$att_id = $type.'_'.$id;
		$element->setAttId($att_id);
		$element->save();
		$this->createInFile($fileName, $att_id, $table, $projectName);
		echo json_encode(array('paula_type'=>$type, 'paula_id'=>$paula_id,
				'elementId'=>$id));
		return sfView::NONE;
	}
	
	public function executeRestoreElement(sfWebRequest $request) {
		$id_annoset = $request->getParameter("annoset");
		$annoset = Doctrine::getTable("annoset")->find($id_annoset);
		$projectName = $annoset->getName();
		$table = $request->getParameter('table');
		$type = $request->getParameter('type');
		$attId = $request->getParameter('attId');
		$id = $request->getParameter('id');
		
		$test = Doctrine::getTable($table)
		->findOneByIdAnnosetAndListType($id_annoset, $type);
		
		$paula_id = $test->getPaulaId();
		
		$base = $test->getBase();
		$fileName = $test->getFile()->getName();
		if($table == 'Mark'){
			$element = new Mark();
			$element->setHref("");
		}
		elseif($table == 'Struct')
			$element = new Struct();
			
		$element->setIdAnnoset($id_annoset);
		$element->setPaulaId($paula_id);
		$element->setListType($type);
		if($base !== null)
			$element->setBase($base);
		
		$element->save();
		$element->setId($id);	
		$element->setAttId($attId);
		$element->save();
		
		echo "ok";
		return sfView::NONE;
	}

	public function executeAddLink(sfWebRequest $request){
		$response = "not yet implemented";
		$annoset_id = $request->getParameter('annoset_id');
		$elementFrom = json_decode($request->getParameter('from'), true);
		$elementTo = json_decode($request->getParameter('to'), true);
		$annoset = Doctrine::getTable('Annoset')->find($annoset_id);
		$project_name = $annoset->getName();
		$idRel = $request->getParameter('idRel');
		$rel_attId = $request->getParameter("relAttId");
		try{
			if($elementFrom['paula_type'] == 'tok')
			throw new Exception();
			$fileFrom = Doctrine::getTable('File')
			->findOneByIdAnnosetAndPaulaId($annoset_id, $elementFrom['paula_id']);
			$fileTo = Doctrine::getTable('File')
			->findOneByIdAnnosetAndPaulaId($annoset_id, $elementTo['paula_id']);
			if($fileFrom->getType() == 'Struct'){
				$struct = Doctrine::getTable('Struct')->find($elementFrom['elementId']);
				$base = $struct->getBase();
				if($base){
					if($base != $fileTo->getName())
					throw new Exception();
				}
				$rel = new Rel();
				$rel->setIdStruct($elementFrom['elementId']);
				$prefix = '#';
				if(!$base)
				$prefix = $fileTo->getName().'#';
				$rel->setHref($prefix.$elementTo['attId']);
				$rel->save();
				if(!empty($idRel)) {
					$rel->setId($idRel);
				}
				
				if(empty($rel_attId)) 
					$rel_attId = 'rel_'.$rel->getId();
					
				$rel->setAttId($rel_attId);
				
				$rel->save();
				//update in file
				$this->createRelInFile($fileFrom->getName(), $elementFrom['attId'],
				$project_name, $rel);
				//set response
				$response = $rel->getId();
			}
			elseif($fileFrom->getType() == 'Mark'){
				$mark = Doctrine::getTable('Mark')->find($elementFrom['elementId']);
				$href = $mark->getHref();
				$array = Paula::XlinkToArray($href);
				$newEntry = $elementTo['attId'];
				if(!$mark->getBase()){
					$prefix =$fileTo->getName();
					$newEntry = $prefix.'#'.$newEntry;
				}
				elseif($mark->getBase()!= $fileTo->getName())
				throw new Exception();
				array_push($array, $newEntry);
				$newHref = Paula::arrayToXlink($array);
				$mark->setHref($newHref);
				$mark->save();
				//update in file
				$this->updateHrefInFile($fileFrom->getName(), 'mark', $href, $newHref, $project_name);
				//set response
				$response = 'l';
			}
		} catch(Exception $e){
			echo $e->getMessage();
			$response = 'cannot link those elements';
		}
		return $this->renderText(json_encode($response));
	}
	
	public function executeGetRelAttId(sfWebRequest $request) {
		$idRel = $request->getParameter("idRel");
		if(!empty($idRel)) {
			$rel = Doctrine::getTable("Rel")->findOneById($idRel);
			echo $rel->getAttId();
		} else {
			echo "error";
		}
		return sfView::NONE;
	}
	
	public function executeUpdateElementPosition(sfWebRequest $request){
		$id_annoset = $request->getParameter("annoset_id");
		$paula_id = $request->getParameter("paula_id");
		$element_id = $request->getParameter("elementId");
		$x_position = $request->getParameter("x_position");
		$y_position = $request->getParameter("y_position");
		$table = Doctrine::getTable("File")->findOneByIdAnnosetAndPaulaId($id_annoset,
				$paula_id)->getType();
		$element = Doctrine::getTable($table)->find($element_id);
		$element->setXPosition($x_position);
		$element->setYPosition($y_position);
		$element->save();
		return sfView::NONE;
	}

	private function checkHrefWithId($href, $att_id){
		$array = Paula::XlinkToArray($href);
		if(in_array($att_id, $array) && count($array) == 1)
		return true;
		else return false;
	}

	private function deleteInFile($fileName, $eltId, $type, $projectName){
		$doc = new DOMDocument();
		$doc->formatOutput = true;
		$doc->preserveWhiteSpace = false;
		if(!$doc->load("uploads/projects/".$projectName."/".$fileName))
		return false;
		$elements = $doc->getElementsByTagName($type);
		foreach($elements as $element){
			if($element->getAttribute('id') == $eltId){
				$element->parentNode->removeChild($element);
			}
		}
		$doc->save("uploads/projects/".$projectName."/".$fileName);
	}

	private function deleteInFileByHref($fileName, $href, $projectName){
		$doc = new DOMDocument();
		$doc->formatOutput = true;
		$doc->preserveWhiteSpace = false;
		if(!$doc->load("uploads/projects/".$projectName."/".$fileName))
		return false;
		$paula = $doc->documentElement;
		$node = $paula->firstChild->nextSibling;
		if($node->nodeName == 'featList')
		$type = 'feat';
		else if($node->nodeName == 'multiFeatList')
		$type = 'multiFeat';
		$elements = $doc->getElementsByTagName($type);
		foreach($elements as $element){
			if($element->getAttribute('xlink:href') == $href){
				$element->parentNode->removeChild($element);
			}
		}
		$doc->save("uploads/projects/".$projectName."/".$fileName);
	}

	private function deleteElementById($fileName,  $id_element, $projectName){
		/*$doc = new DOMDocument();
		$doc->formatOutput = true;
		$doc->preserveWhiteSpace = false;
		if(!$doc->load("uploads/projects/".$projectName."/".$fileName))
		return false;
		$xpath = new DOMXPath($doc);
		$path = "//*[@id = '".$id_element."']";
		$element = $xpath->query($path)->item(0);
		$element->parentNode->removeChild($element);
		$doc->save("uploads/projects/".$projectName."/".$fileName);*/
	}

	private function updateHrefInFile($fileName, $type, $href, $newHref, $projectName){
		$doc = new DOMDocument();
		$doc->formatOutput = true;
		$doc->preserveWhiteSpace = false;
		if(!$doc->load("uploads/projects/".$projectName."/".$fileName))
		return false;
		$elements = $doc->getElementsByTagName($type);
		foreach($elements as $element){
			if($element->getAttribute('xlink:href') == $href)
			$element->setAttribute("xlink:href", $newHref);
		}
		$doc->save("uploads/projects/".$projectName."/".$fileName);
	}

	private function feedListByElementType(&$featsLists, $elements, $id, $table){
		$typeArray = array();
		$nameArray = array();
		foreach($elements as $element){
			$type = $element->getListType();
			if($type == 'annoSet')
			continue;
			$pattern = '%'.$element->getAttId().'%';
			$feats = Doctrine::getTable('Feat')->createQuery('f')->where('f.id_annoset = ?', $id)
			->addWhere('f.href LIKE ?', $pattern)->execute();
			if(!in_array($type, $typeArray)){
				$featsLists[$type] = array();
				$featsLists[$type]['table'] = $table;
				$featsLists[$type]['list'] = array();
				$nameArray[$type] = array();
				$typeArray[] = $type;
			}
			foreach($feats as $feat){
				$name = $feat->getName();
				$paula_id = $feat->getPaulaId();
				if($name === null){
					$name = $feat->getListType();
				}
				if(!in_array($name, $nameArray[$type])){
					$nameArray[$type][] = $name;
					$featsLists[$type]['list'][$name] = array('values'=> array(),
							'paula_id'=>$paula_id);
				}
				$value = $feat->getValue();
				if(!in_array($value, $featsLists[$type]['list'][$name]['values']))
				array_push($featsLists[$type]['list'][$name]['values'], $value);
			}
		}
	}

	private function addFeat($projectName, $file_name, $name, $value, $elementId,
	$elementFileName, $id_annoset){
		$doc = new DOMDocument();
		$doc->formatOutput = true;
		$doc->preserveWhiteSpace = false;
		if(!$doc->load("uploads/projects/".$projectName."/".$file_name))
		return false;
		$paula = $doc->documentElement;
		$header = $paula->firstChild;
		$parentNode = $paula->firstChild->nextSibling;
		$prefix = ($parentNode->hasAttribute('xml:base'))? "" : $elementFileName;
		$base = ($parentNode->hasAttribute('xml:base'))? $elementFileName : null;
		$featElement = $doc->createElement('feat');
		$featDB = new Feat();
		$featDB->setIdAnnoset($id_annoset);
		$featDB->setPaulaId($header->getAttribute('paula_id'));
		if($base){
			$featDB->setBase($base);
		}
		$featDB->setListType($parentNode->getAttribute('type'));
		switch($parentNode->nodeName){
			case 'multiFeatList':
				$nodeList = $parentNode->getElementsByTagName('multiFeat');
				$isReferenced = false;
				foreach($nodeList as $node){
					if(preg_match('/'.$elementId.'/', $node->getAttribute('xlink:href')) != 0){
						$parentNode = $node;
						$isReferenced = true;
						break;
					}
				}
				if(!$isReferenced){
					$element = $doc->createElement('multiFeat');
					$multiFeat = $parentNode->appendChild($element);
					$multiFeat->setAttribute('xlink:href', $prefix.'#'.$elementId);
					$parentNode = $multiFeat;
				}
				$featDB->setHref($parentNode->getAttribute('xlink:href'));
				$feat = $parentNode->appendChild($featElement);
				$feat->setAttribute('name', $name);
				$featDB->setName($name);
				break;
			case 'featList':
				$feat = $parentNode->appendChild($featElement);
				$feat->setAttribute('xlink:href', $prefix.'#'.$elementId);
				$featDB->setHref($feat->getAttribute('xlink:href'));
				break;
			default:
				break;
		}
		$feat->setAttribute('value', $value);
		$featDB->setValue($value);
		$featDB->save();
		$doc->save("uploads/projects/".$projectName."/".$file_name);
	}

	private function createInFile($fileName, $eltId, $type, $projectName){
		$doc = new DOMDocument();
		$doc->formatOutput = true;
		$doc->preserveWhiteSpace = false;
		if(!$doc->load("uploads/projects/".$projectName."/".$fileName))
		return false;
		$paula = $doc->documentElement;
		$parentNode = $paula->firstChild->nextSibling;
		$type = mb_strtolower($type, 'UTF-8');
		$element =$doc->createElement($type);
		$newNode = $parentNode->appendChild($element);
		$newNode->setAttribute("id", $eltId);
		if($type == 'mark'){
			$newNode->setAttribute("xlink:href", "");
		}
		$doc->save("uploads/projects/".$projectName."/".$fileName);
	}

	private function createRelInFile($fileName, $eltId, $projectName, $relDB){
		$doc = new DOMDocument();
		$doc->formatOutput = true;
		$doc->preserveWhiteSpace = false;
		if(!$doc->load("uploads/projects/".$projectName."/".$fileName))
		return false;
		$doc->validate();
		$element = $doc->getElementById($eltId);
		$newElement = $doc->createElement('rel');
		$rel = $element->appendChild($newElement);
		$rel->setAttribute('id', $relDB->getAttId());
		$rel->setAttribute('xlink:href', $relDB->getHref());
		if($relDB->getType())
		$rel->setAttribute('type', $relDB->getType());
		$doc->save("uploads/projects/".$projectName."/".$fileName);
	}

}
